<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Scene Reconstruction</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d3/d81/tutorial_contrib_root.html">Tutorials for contrib modules</a></li><li class="navelem"><a class="el" href="../../de/d7c/tutorial_table_of_content_sfm.html">Structure From Motion</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Scene Reconstruction </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>Goal </h2>
<p>In this tutorial you will learn how to use the reconstruction api for sparse reconstruction:</p>
<ul>
<li>Load and file with a list of image paths.</li>
<li>Run libmv reconstruction pipeline.</li>
<li>Show obtained results using Viz.</li>
</ul>
<h2>Code </h2>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d3/df9/sfm_8hpp.html">opencv2/sfm.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d0/d7e/viz_8hpp.html">opencv2/viz.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d2/d28/calib3d_8hpp.html">opencv2/calib3d.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d0/d9c/core_2include_2opencv2_2core_8hpp.html">opencv2/core.hpp</a>&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../db/db0/namespacecv_1_1sfm.html">cv::sfm</a>;</div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> help() {</div><div class="line">  cout</div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;\n------------------------------------------------------------------------------------\n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot; This program shows the multiview reconstruction capabilities in the \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot; OpenCV Structure From Motion (SFM) module.\n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot; It reconstruct a scene from a set of 2D images \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot; Usage:\n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;        example_sfm_scene_reconstruction &lt;path_to_file&gt; &lt;f&gt; &lt;cx&gt; &lt;cy&gt;\n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot; where: path_to_file is the file absolute path into your system which contains\n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;        the list of images to use for reconstruction. \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;        f  is the focal length in pixels. \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;        cx is the image principal point x coordinates in pixels. \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;        cy is the image principal point y coordinates in pixels. \n&quot;</span></div><div class="line">      &lt;&lt; <span class="stringliteral">&quot;------------------------------------------------------------------------------------\n\n&quot;</span></div><div class="line">      &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span> getdir(<span class="keyword">const</span> <span class="keywordtype">string</span> _filename, vector&lt;String&gt; &amp;files)</div><div class="line">{</div><div class="line">  ifstream myfile(_filename.c_str());</div><div class="line">  <span class="keywordflow">if</span> (!myfile.is_open()) {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Unable to read file: &quot;</span> &lt;&lt; _filename &lt;&lt; endl;</div><div class="line">    exit(0);</div><div class="line">  } <span class="keywordflow">else</span> {;</div><div class="line">    <span class="keywordtype">size_t</span> found = _filename.find_last_of(<span class="stringliteral">&quot;/\\&quot;</span>);</div><div class="line">    <span class="keywordtype">string</span> line_str, path_to_file = _filename.substr(0, found);</div><div class="line">    <span class="keywordflow">while</span> ( getline(myfile, line_str) )</div><div class="line">      files.push_back(path_to_file+<span class="keywordtype">string</span>(<span class="stringliteral">&quot;/&quot;</span>)+line_str);</div><div class="line">  }</div><div class="line">  <span class="keywordflow">return</span> 1;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])</div><div class="line">{</div><div class="line">  <span class="comment">// Read input parameters</span></div><div class="line"></div><div class="line">  <span class="keywordflow">if</span> ( argc != 5 )</div><div class="line">  {</div><div class="line">    help();</div><div class="line">    exit(0);</div><div class="line">  }</div><div class="line"></div><div class="line">  <span class="comment">// Parse the image paths</span></div><div class="line"></div><div class="line">  vector&lt;String&gt; images_paths;</div><div class="line">  getdir( argv[1], images_paths );</div><div class="line"></div><div class="line"></div><div class="line">  <span class="comment">// Build intrinsics</span></div><div class="line"></div><div class="line">  <span class="keywordtype">float</span> f  = atof(argv[2]),</div><div class="line">        cx = atof(argv[3]), cy = atof(argv[4]);</div><div class="line"></div><div class="line">  <a class="code" href="../../de/de1/classcv_1_1Matx.html">Matx33d</a> K = <a class="code" href="../../dc/d84/group__core__basic.html#gaff0100a48f049fb15584a4a657eae838">Matx33d</a>( f, 0, cx,</div><div class="line">                       0, f, cy,</div><div class="line">                       0, 0,  1);</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">  <span class="keywordtype">bool</span> is_projective = <span class="keyword">true</span>;</div><div class="line">  vector&lt;Mat&gt; Rs_est, ts_est, points3d_estimated;</div><div class="line">  <a class="code" href="../../da/db5/group__reconstruction.html#ga279c084302ae1d7541d458e4b23fabd3">reconstruct</a>(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective);</div><div class="line"></div><div class="line"></div><div class="line">  <span class="comment">// Print output</span></div><div class="line"></div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;\n----------------------------\n&quot;</span> &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Reconstruction: &quot;</span> &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;============================&quot;</span> &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Estimated 3D points: &quot;</span> &lt;&lt; points3d_estimated.size() &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Estimated cameras: &quot;</span> &lt;&lt; Rs_est.size() &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Refined intrinsics: &quot;</span> &lt;&lt; endl &lt;&lt; K &lt;&lt; endl &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;3D Visualization: &quot;</span> &lt;&lt; endl;</div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;============================&quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">  <a class="code" href="../../d6/d32/classcv_1_1viz_1_1Viz3d.html">viz::Viz3d</a> window(<span class="stringliteral">&quot;Coordinate Frame&quot;</span>);</div><div class="line">             window.setWindowSize(<a class="code" href="../../dc/d84/group__core__basic.html#ga346f563897249351a34549137c8532a0">Size</a>(500,500));</div><div class="line">             window.setWindowPosition(<a class="code" href="../../dc/d84/group__core__basic.html#ga1e83eafb2d26b3c93f09e8338bcab192">Point</a>(150,150));</div><div class="line">             window.setBackgroundColor(); <span class="comment">// black by default</span></div><div class="line"></div><div class="line">  <span class="comment">// Create the pointcloud</span></div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Recovering points  ... &quot;</span>;</div><div class="line"></div><div class="line">  <span class="comment">// recover estimated points3d</span></div><div class="line">  vector&lt;Vec3f&gt; point_cloud_est;</div><div class="line">  <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; points3d_estimated.size(); ++i)</div><div class="line">    point_cloud_est.push_back(<a class="code" href="../../d6/dcf/classcv_1_1Vec.html">Vec3f</a>(points3d_estimated[i]));</div><div class="line"></div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;[DONE]&quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line"></div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;Recovering cameras ... &quot;</span>;</div><div class="line"></div><div class="line">  vector&lt;Affine3d&gt; path;</div><div class="line">  <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i &lt; Rs_est.size(); ++i)</div><div class="line">    path.push_back(<a class="code" href="../../dd/d99/classcv_1_1Affine3.html">Affine3d</a>(Rs_est[i],ts_est[i]));</div><div class="line"></div><div class="line">  cout &lt;&lt; <span class="stringliteral">&quot;[DONE]&quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line"></div><div class="line">  <span class="keywordflow">if</span> ( point_cloud_est.size() &gt; 0 )</div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Rendering points   ... &quot;</span>;</div><div class="line"></div><div class="line">    <a class="code" href="../../db/d82/classcv_1_1viz_1_1WCloud.html">viz::WCloud</a> cloud_widget(point_cloud_est, viz::Color::green());</div><div class="line">    window.showWidget(<span class="stringliteral">&quot;point_cloud&quot;</span>, cloud_widget);</div><div class="line"></div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;[DONE]&quot;</span> &lt;&lt; endl;</div><div class="line">  }</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Cannot render points: Empty pointcloud&quot;</span> &lt;&lt; endl;</div><div class="line">  }</div><div class="line"></div><div class="line"></div><div class="line">  <span class="keywordflow">if</span> ( path.size() &gt; 0 )</div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Rendering Cameras  ... &quot;</span>;</div><div class="line"></div><div class="line">    window.showWidget(<span class="stringliteral">&quot;cameras_frames_and_lines&quot;</span>, <a class="code" href="../../d0/da3/classcv_1_1viz_1_1WTrajectory.html">viz::WTrajectory</a>(path, viz::WTrajectory::BOTH, 0.1, viz::Color::green()));</div><div class="line">    window.showWidget(<span class="stringliteral">&quot;cameras_frustums&quot;</span>, <a class="code" href="../../da/d80/classcv_1_1viz_1_1WTrajectoryFrustums.html">viz::WTrajectoryFrustums</a>(path, K, 0.1, viz::Color::yellow()));</div><div class="line"></div><div class="line">    window.setViewerPose(path[0]);</div><div class="line"></div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;[DONE]&quot;</span> &lt;&lt; endl;</div><div class="line">  }</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">  {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Cannot render the cameras: Empty path&quot;</span> &lt;&lt; endl;</div><div class="line">  }</div><div class="line"></div><div class="line">  cout &lt;&lt; endl &lt;&lt; <span class="stringliteral">&quot;Press &#39;q&#39; to close each windows ... &quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line">  window.spin();</div><div class="line"></div><div class="line">  <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2>Explanation </h2>
<p>Firstly, we need to load the file containing list of image paths in order to feed the reconstruction api:</p>
<div class="fragment"><div class="line">/home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2889.jpg</div><div class="line">/home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2890.jpg</div><div class="line">/home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2891.jpg</div><div class="line">/home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2892.jpg</div><div class="line"></div><div class="line">...</div><div class="line"></div><div class="line">int getdir(<span class="keyword">const</span> <span class="keywordtype">string</span> _filename, vector&lt;string&gt; &amp;files)</div><div class="line">{</div><div class="line">  ifstream myfile(_filename.c_str());</div><div class="line">  <span class="keywordflow">if</span> (!myfile.is_open()) {</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;Unable to read file: &quot;</span> &lt;&lt; _filename &lt;&lt; endl;</div><div class="line">    exit(0);</div><div class="line">  } <span class="keywordflow">else</span> {</div><div class="line">    <span class="keywordtype">string</span> line_str;</div><div class="line">    <span class="keywordflow">while</span> ( getline(myfile, line_str) )</div><div class="line">      files.push_back(line_str);</div><div class="line">  }</div><div class="line">  <span class="keywordflow">return</span> 1;</div><div class="line">}</div></div><!-- fragment --><p>Secondly, the built container will be used to feed the reconstruction api. It is important outline that the estimated results must be stored in a vector&lt;Mat&gt;. In this case is called the overloaded signature for real images which from the images, internally extracts and compute the sparse 2d features using DAISY descriptors in order to be matched using FlannBasedMatcher and build the tracks structure.</p>
<div class="fragment"><div class="line"><span class="keywordtype">bool</span> is_projective = <span class="keyword">true</span>;</div><div class="line">vector&lt;Mat&gt; Rs_est, ts_est, points3d_estimated;</div><div class="line"><a class="code" href="../../da/db5/group__reconstruction.html#ga279c084302ae1d7541d458e4b23fabd3">reconstruct</a>(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective);</div><div class="line"></div><div class="line"><span class="comment">// Print output</span></div><div class="line"></div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;\n----------------------------\n&quot;</span> &lt;&lt; endl;</div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;Reconstruction: &quot;</span> &lt;&lt; endl;</div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;============================&quot;</span> &lt;&lt; endl;</div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;Estimated 3D points: &quot;</span> &lt;&lt; points3d_estimated.size() &lt;&lt; endl;</div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;Estimated cameras: &quot;</span> &lt;&lt; Rs_est.size() &lt;&lt; endl;</div><div class="line">cout &lt;&lt; <span class="stringliteral">&quot;Refined intrinsics: &quot;</span> &lt;&lt; endl &lt;&lt; K &lt;&lt; endl &lt;&lt; endl;</div></div><!-- fragment --><p>Finally, the obtained results will be shown in Viz.</p>
<h2>Usage and Results </h2>
<p>In order to run this sample we need to specify the path to the image paths files, the focal length of the camera in addition to the center projection coordinates (in pixels).</p>
<p><b>1. Middlebury temple</b></p>
<p>Using following image sequence [1] and the followings camera parameters we can compute the sparse 3d reconstruction:</p>
<div class="fragment"><div class="line">./example_sfm_scene_reconstruction image_paths_file.txt 800 400 225</div></div><!-- fragment --><div class="image">
<img src="../../temple_input.jpg" alt="temple_input.jpg"/>
</div>
<p>The following picture shows the obtained camera motion in addition to the estimated sparse 3d reconstruction:</p>
<div class="image">
<img src="../../temple_reconstruction.jpg" alt="temple_reconstruction.jpg"/>
</div>
<p><b>2. Sagrada Familia</b></p>
<p>Using following image sequence [2] and the followings camera parameters we can compute the sparse 3d reconstruction:</p>
<div class="fragment"><div class="line">./example_sfm_scene_reconstruction image_paths_file.txt 350 240 360</div></div><!-- fragment --><div class="image">
<img src="../../sagrada_familia_input.jpg" alt="sagrada_familia_input.jpg"/>
</div>
<p>The following picture shows the obtained camera motion in addition to the estimated sparse 3d reconstruction:</p>
<div class="image">
<img src="../../sagrada_familia_reconstruction.jpg" alt="sagrada_familia_reconstruction.jpg"/>
</div>
<p>[1] <a href="http://vision.middlebury.edu/mview/data">http://vision.middlebury.edu/mview/data</a></p>
<p>[2] Penate Sanchez, A. and Moreno-Noguer, F. and Andrade Cetto, J. and Fleuret, F. (2014). LETHA: Learning from High Quality Inputs for 3D Pose Estimation in Low Quality Images. Proceedings of the International Conference on 3D vision (3DV). <a href="http://www.iri.upc.edu/research/webprojects/pau/datasets/sagfam">URL</a> </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:39 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
